package com.itheima.service.mongo.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.itheima.domain.mongo.*;
import com.itheima.service.mongo.MovementService;
import com.itheima.util.ConstantUtil;
import com.itheima.vo.PageBeanVo;
import org.apache.dubbo.config.annotation.DubboService;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;

import java.util.ArrayList;
import java.util.List;

@DubboService
public class MovementServiceImpl implements MovementService {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private RedisPidService redisPidService;

    @Override
    public void saveMovement(Movement movement) {
        // 0.生成大数据pid
        Long pid = redisPidService.getNextPid(ConstantUtil.MOVEMENT_ID);
        // 1.保存动态详情
        movement.setPid(pid); // 指定大数据pid
        mongoTemplate.save(movement);
        // 2.保存个人动态
        MyMovement myMovement = new MyMovement();
        myMovement.setCreated(movement.getCreated()); // 发布时间
        myMovement.setPublishId(movement.getId()); // 动态id
        mongoTemplate.save(myMovement, ConstantUtil.MOVEMENT_MINE + movement.getUserId()); // 需要指定表名
        // 3.查询我的好友
        Query query = new Query(Criteria.where("userId").is(movement.getUserId()));
        List<Friend> friendList = mongoTemplate.find(query, Friend.class);
        // 4.遍历好友，保存好友动态表
        if (CollectionUtil.isNotEmpty(friendList)) {
            for (Friend friend : friendList) {
                // 获取好友id
                Long friendId = friend.getFriendId();
                // 保存好友动态表
                FriendMovement friendMovement = new FriendMovement();
                friendMovement.setUserId(movement.getUserId()); // 你的id
                friendMovement.setPublishId(movement.getId()); // 你动态的id
                friendMovement.setCreated(movement.getCreated()); // 你动态的发布时间
                mongoTemplate.save(friendMovement, ConstantUtil.MOVEMENT_FRIEND + friendId);
            }
        }
    }

    // 查看个人动态
    @Override
    public PageBeanVo findMyMovement(Long userId, Integer pageNum, Integer pageSize) {
        // 1.构建条件
        Integer index = (pageNum - 1) * pageSize;
        Query query = new Query().with(Sort.by(Sort.Order.desc("created"))).skip(index).limit(pageSize);
        // 2.查询个人动态
        List<MyMovement> myMovementList = mongoTemplate.find(query, MyMovement.class, ConstantUtil.MOVEMENT_MINE + userId);
        // 3.查询动态详情
        List<Movement> movementList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(myMovementList)) {
            for (MyMovement myMovement : myMovementList) {
                // 动态id
                ObjectId publishId = myMovement.getPublishId();
                // 查询动态详情
                Movement movement = mongoTemplate.findById(publishId, Movement.class);
                // 判断审核状态
                if (movement.getState() == 1) {
                    movementList.add(movement);
                }
            }
        }
        // 4.查询个人动态总记录数
        long total = mongoTemplate.count(query, MyMovement.class, ConstantUtil.MOVEMENT_MINE + userId);
        // 5.返回并封装pageBeanVo
        return new PageBeanVo(pageNum, pageSize, total, movementList);
    }

    // 查看好友动态
    @Override
    public PageBeanVo findFriendMovement(Long userId, Integer pageNum, Integer pageSize) {
        // 1.构建查询条件
        Integer index = (pageNum - 1) * pageSize;
        Query query = new Query().with(Sort.by(Sort.Order.desc("created"))).skip(index).limit(pageSize);
        // 2.查询登录人的好友动态表
        List<FriendMovement> friendMovementList = mongoTemplate.find(query, FriendMovement.class, ConstantUtil.MOVEMENT_FRIEND + userId);
        // 3.遍历好友动态
        List<Movement> movementList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(friendMovementList)) {
            for (FriendMovement friendMovement : friendMovementList) {
                // 获取好友动态id
                ObjectId publishId = friendMovement.getPublishId();
                // 查询好友动态详情
                Movement movement = mongoTemplate.findById(publishId, Movement.class);
                // 判断是否审核通过
                if (movement.getState() == 1) {
                    // 添加到集合
                    movementList.add(movement);
                }
            }
        }
        // 4.查询总记录数
        long total = mongoTemplate.count(query, FriendMovement.class, ConstantUtil.MOVEMENT_FRIEND + userId);
        // 5.封装并返回分页对象
        return new PageBeanVo(pageNum, pageSize, total, movementList);
    }

    // 查看推荐动态
    @Override
    public PageBeanVo findRecommendMovement(Long userId, Integer pageNum, Integer pageSize) {
        // 1.构建查询条件
        Integer index = (pageNum - 1) * pageSize;
        Query query = new Query(Criteria.where("userId").is(userId))
                .with(Sort.by(Sort.Order.desc("score")))
                .skip(index).limit(pageSize);
        // 2.查询推荐动态
        List<RecommendMovement> recommendList = mongoTemplate.find(query, RecommendMovement.class);
        // 3.遍历推荐动态查询动态详情
        List<Movement> movementList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(recommendList)) {
            for (RecommendMovement recommend : recommendList) {
                // 获取动态id
                ObjectId publishId = recommend.getPublishId();
                // 查询动态详情
                Movement movement = mongoTemplate.findById(publishId, Movement.class);
                // 设置动态详情到集合
                movementList.add(movement);
            }
        }
        // 4.查询总记录数
        long total = mongoTemplate.count(query, RecommendMovement.class);
        // 5.返回并封装分页对象
        return new PageBeanVo(pageNum, pageSize, total, movementList);
    }

    @Override
    public Movement findById(ObjectId id) {
        return mongoTemplate.findById(id, Movement.class);
    }

    // 后台查询动态
    @Override
    public PageBeanVo findMovvementByPage(Integer state, Long userId, Integer pageNum, Integer pageSize) {
        // 1.构建查询条件
        Query query = new Query()
                .with(Sort.by(Sort.Order.desc("created")))
                .skip((pageNum - 1) * pageSize).limit(pageSize);

        // 动态审核
        if (state != null) {
            query.addCriteria(Criteria.where("state").is(state));
        }
        // 用户详情
        if (userId != null) {
            query.addCriteria(Criteria.where("userId").is(userId));
        }

        // 2.查询list
        List<Movement> movementList = mongoTemplate.find(query, Movement.class);

        // 3.查询total
        long total = mongoTemplate.count(query, Movement.class);

        // 4.返回并封装pbv
        return new PageBeanVo(pageNum, pageSize, total, movementList);
    }

    @Override
    public void updateState(Movement movement) {
        mongoTemplate.save(movement);
    }
}
